package common

import (
	"bytes"
	"fmt"
	"log/slog"
	"os/exec"
	"regexp"
	"runtime"
	"strconv"
	"strings"
)

func GetPidByPort(portNumber int) int {
	switch runtime.GOOS {
	case "windows":
		return portInUseByWindows(portNumber)
	case "linux":
		port, _ := portInUseByLinux(portNumber)
		return port
	default:
		slog.Error("不支持的操作系统", "runtime.GOOS", runtime.GOOS)
	}

	return 0
}

// 传入查询的端口号
// 返回端口号对应的进程PID，若没有找到相关进程，返回-1
func portInUseByWindows(portNumber int) int {
	res := -1
	var outBytes bytes.Buffer
	cmdStr := fmt.Sprintf("netstat -ano -p tcp | findstr %d", portNumber)
	cmd := exec.Command("cmd", "/c", cmdStr)
	cmd.Stdout = &outBytes
	cmd.Run()
	resStr := outBytes.String()
	r := regexp.MustCompile(`\s\d+\s`).FindAllString(resStr, -1)
	if len(r) > 0 {
		pid, err := strconv.Atoi(strings.TrimSpace(r[0]))
		if err != nil {
			res = -1
		} else {
			res = pid
		}
	}
	return res
}
func portInUseByLinux(port int) (int, error) {
	cmd := exec.Command("sh", "-c", fmt.Sprintf("netstat -tulnp | grep :%d", port))
	output, err := cmd.CombinedOutput()
	if err != nil {
		return 0, err
	}

	lines := strings.Split(string(output), "\n")
	for _, line := range lines {
		if strings.Contains(line, "LISTEN") {
			parts := strings.Fields(line)
			if len(parts) > 6 {
				pidStr := strings.Split(parts[6], "/")[0]
				pid, _ := strconv.Atoi(pidStr)
				return pid, nil
			}
		}
	}

	return 0, fmt.Errorf("no process found listening on port %d", port)
}
